<?php

require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'exceptions.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'LzArr.php';
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'LzStr.php';


/**
 *  Some useful utilities.
 *
 *  This class is used as namespace. All its methods are static.
 */
class Lz
{
    const PS    = PATH_SEPARATOR;
    const DS    = DIRECTORY_SEPARATOR;


    static public
    function &nit(&$var, $default = NULL)
    {
        if (is_null($var))
            $var    = $default;
        return $var;
    }


    static public
    function &def(&$var, $default = NULL)
    {
        if (self::void($var))
            $var    = $default;
        return $var;
    }


    static public
    function void($var)
    {
        static $notEmpty    = array(0, '0', false);
        return (empty($var) && !in_array($var, $notEmpty, true));
    }


    static public
    function eachable(&$var)
    {
        return is_array($var) || ($var instanceof Traversable);
    }


    static public
    function stringable($var)
    {
        return is_scalar($var) || is_null($var)
                || (is_object($var) && method_exists($var, '__toString'));
    }


    static public
    function copy(&$var)
    {
        if (is_object($var))
            return clone $var;

        return $var;
    }


    /**
     *  Dumps variables.
     *
     *  Takes 1 or more arguments. Outputs mark() before dunping variables.
     *
     *  @param  mixed   $var
     */
    static public
    function dbg($var)
    {
        ob_start();
        $args   = func_get_args();
        echo self::mark('dbg', 1, true), ":\n";
        call_user_func_array('var_dump', $args);
        $buf    = ob_get_clean();

        $buf    = preg_replace('/=>$\s+/m', ' => ', $buf);
        $buf    = preg_replace('/^\s+/m', '\\0\\0', $buf);

        echo "<pre>$buf</pre>\n";
    }


    /**
     *  Outputs caller coordinates.
     *
     *  @param  string  $name   String to output after coordinates
     *  @param  int     $lvl    Caller level.
     *  @param  bool    $return If true, returns string instead of outputing.
     *  @return void/string     Depends on $return argument.
     */
    static public
    function mark($name = '', $lvl = 0, $return = false)
    {
        static $sMark   = 0;

        $trace  = debug_backtrace();
        $file   = $trace[$lvl]['file'];
        $str    = '[mark:' . $sMark++ . '] '
                . join(Lz::DS, array_slice(split(Lz::DS, $file), -3))
                . '(' . $trace[$lvl]['line'] . ') ';

        $pre    = $trace[$lvl + 1];
        if (isset($pre['object']))
            $str    .= '(' . get_class($pre['object']) . ')->';
        if (isset($pre['class']) && (!isset($pre['object'])
                || get_class($pre['object']) != $pre['class']))
            $str    .= $pre['class'] . '::';
        if (isset($pre['function']))
            $str    .= $pre['function'] . '()';

        if ($return)
            return $str;
        else
            echo "<pre>$str $name</pre>\n";
    }


    private
    function __construct()
    {}
}

